package com.anti.modular.sys.consts.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.anti.commom.context.constant.ConstantContext;
import com.anti.commom.core.exception.BusinessException;
import com.anti.commom.enums.CommonStatusEnum;
import com.anti.core.context.login.LoginContextHolder;
import com.anti.jdbc.DBUtils;
import com.anti.jdbc.support.page.PageParam;
import com.anti.jdbc.support.page.PageResult;
import com.anti.modular.sys.consts.entity.SysConfig;
import com.anti.modular.sys.consts.enums.SysConfigExceptionEnum;
import com.anti.modular.sys.consts.param.SysConfigParam;
import com.anti.modular.sys.consts.service.SysConfigService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description TODO
 * @Author anTi
 * @Date 2021-3-15
 */
@Service
public class SysConfigServiceImpl implements SysConfigService {
    @Resource
    DBUtils dbUtils;
    @Override
    public PageResult page(PageParam pageParam, SysConfigParam sysConfigParam) {
        //构造查询条件
        StringBuilder sb=new StringBuilder("select * from sys_config where status<>2 ");
        ArrayList<Object> params = CollectionUtil.newArrayList();

        if (ObjectUtil.isNotNull(sysConfigParam)) {
            //如果名称不为空，则带上名称搜素搜条件
            if (ObjectUtil.isNotEmpty(sysConfigParam.getName())) {
                sb.append(" and name like  ? ");
                params.add("%"+sysConfigParam.getName()+"%");
            }
            //如果常量编码不为空，则带上常量编码搜素搜条件
            if (ObjectUtil.isNotEmpty(sysConfigParam.getCode())) {
                sb.append(" and code like  ? ");
                params.add("%"+sysConfigParam.getCode()+"%");
            }
            //如果分类编码不为空，则带上分类编码
            if (ObjectUtil.isNotEmpty(sysConfigParam.getGroupCode())) {
                sb.append(" and group_code =  ? ");
                params.add(sysConfigParam.getGroupCode());
            }
        }
        //按类型升序排列，同类型的排在一起
        sb.append(" order by group_code desc ");
        PageResult pageResult = dbUtils.query(pageParam, sb.toString(), params.toArray());
        return pageResult;
    }

    @Override
    public List<SysConfig> list(SysConfigParam sysConfigParam) {
        //查询未删除的
        String sql="select * from sys_config where status<>2 ";
        return dbUtils.query(sql,SysConfig.class);
    }

    @Override
    public SysConfig detail(SysConfigParam sysConfigParam) {
        return this.querySysConfig(sysConfigParam);
    }

    @Override
    public void add(SysConfigParam sysConfigParam) {
        //1.校验参数，是否有重复的名称和编码，不排除当前记录
        checkRepeatParam(sysConfigParam, false);

        //2.构造实体
        SysConfig sysConfig = new SysConfig();
        BeanUtil.copyProperties(sysConfigParam, sysConfig);
        sysConfig.setStatus(CommonStatusEnum.ENABLE.getCode());
        sysConfig.setCreateTime(new Date());
        sysConfig.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        //3.保存到库中
        dbUtils.insert(sysConfig);

        //4.添加对应context
        ConstantContext.putConstant(sysConfigParam.getCode(), sysConfigParam.getValue());
    }

    @Override
    public void delete(SysConfigParam sysConfigParam) {
        //1.根据id获取常量
        SysConfig sysConfig = this.querySysConfig(sysConfigParam);
        //2.不能删除系统参数
        if ("Y".equals(sysConfig.getSysFlag())) {
            throw new BusinessException(SysConfigExceptionEnum.CONFIG_SYS_CAN_NOT_DELETE);
        }
        //3.设置状态为已删除
        sysConfig.setStatus(CommonStatusEnum.DELETED.getCode());
        sysConfig.setUpdateTime(new Date());
        sysConfig.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(sysConfig);
        //4.删除对应context
        ConstantContext.deleteConstant(sysConfigParam.getCode());
    }

    @Override
    public void edit(SysConfigParam sysConfigParam) {
        //1.根据id获取常量信息
        SysConfig sysConfig = this.querySysConfig(sysConfigParam);

        //2.校验参数，是否有重复的名称和编码，排除本条记录
        checkRepeatParam(sysConfigParam, true);

        //请求参数转化为实体
        BeanUtil.copyProperties(sysConfigParam, sysConfig);
        //不能修改状态，用修改状态接口修改状态
        sysConfig.setStatus(null);
        sysConfig.setUpdateTime(new Date());
        sysConfig.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        //3.更新记录
        dbUtils.update(sysConfig);
        //4.更新对应常量context
        ConstantContext.putConstant(sysConfigParam.getCode(), sysConfigParam.getValue());
    }

    /**
     * 校验参数，是否有重复的名称和编码
     */
    private void checkRepeatParam(SysConfigParam sysConfigParam, boolean isExcludeSelf) {
        Long id = sysConfigParam.getId();
        String name = sysConfigParam.getName();
        String code = sysConfigParam.getCode();

        //构建带name和code的查询条件
        StringBuilder nameSb=new StringBuilder("select count(*) from sys_config where status <> 2 and name =? ");
        ArrayList<Object> nameParams = CollectionUtil.newArrayList();
        nameParams.add(name);


        StringBuilder codeSb=new StringBuilder("select count(*) from sys_config where status <> 2 and code =? ");
        ArrayList<Object> codeParams = CollectionUtil.newArrayList();
        codeParams.add(code);


        //如果排除自己，则增加查询条件主键id不等于本条id
        if (isExcludeSelf) {
            nameSb.append(" and id <> ?");
            codeSb.append(" and id <> ?");
            nameParams.add(id);
            codeParams.add(id);
        }

        //查询重复记录的数量
        int countByName = dbUtils.getIntValue(nameSb.toString(),nameParams.toArray());
        int countByCode = dbUtils.getIntValue(codeSb.toString(),codeParams.toArray());

        //如果存在重复的记录，抛出异常，直接返回前端
        if (countByName >= 1) {
            throw new BusinessException(SysConfigExceptionEnum.CONFIG_NAME_REPEAT);
        }
        if (countByCode >= 1) {
            throw new BusinessException(SysConfigExceptionEnum.CONFIG_CODE_REPEAT);
        }
    }

    /**
     * 获取系统参数配置
     */
    private SysConfig querySysConfig(SysConfigParam sysConfigParam) {
        SysConfig sysConfig = dbUtils.get("select * from sys_config where id=?",SysConfig.class,sysConfigParam.getId());
        if (ObjectUtil.isEmpty(sysConfig)) {
            throw new BusinessException(SysConfigExceptionEnum.CONFIG_NOT_EXIST);
        }
        return sysConfig;
    }
}
